home *** CD-ROM | disk | FTP | other *** search
Prolog Source | 1986-10-07 | 8.6 KB | 368 lines |
- /* SYMBOLIC DIFFERENTIATION EXAMPLE */
-
- DOMAINS
- /*
- The input string is converted to a list of
- tokens
- */
-
- TOKL = STRING*
-
- /*
- Expressions are modeled via EXP
- */
- EXP=var(STRING);
- int(INTEGER);
- plus(EXP,EXP);
- minus(EXP,EXP);
- mult(EXP,EXP);
- div(EXP,EXP);
- ln(EXP);
- potens(EXP,EXP)
-
- PREDICATES
- run
- diff
- d(EXP,STRING,EXP);
- readexp(EXP);
- checkhelp(char)
- check(EXP,TOKL);
-
- writeexp(EXP);
- writePOTENS(EXP);
- writeMULT(EXP);
- writeMINUS(EXP);
- writeDIV(EXP);
- writePAR(EXP);
-
- tokl(STRING,TOKL); /* Scanner */
- front(STRING,TOKL,TOKL);
-
- s_exp(TOKL,TOKL,EXP); /* Parser */
- potensexp(TOKL,TOKL,EXP);
- potensexp1(TOKL,TOKL,EXP,EXP);
- multexp(TOKL,TOKL,EXP);
- multexp1(TOKL,TOKL,EXP,EXP);
- plusexp(TOKL,TOKL,EXP);
- plusexp1(TOKL,TOKL,EXP,EXP);
- elmexp(TOKL,TOKL,EXP);
-
- reduce(EXP,EXP); /* Reducer */
- plusr(EXP,EXP,EXP);
- minusr(EXP,EXP,EXP);
- multr(EXP,EXP,EXP);
- divr(EXP,EXP,EXP);
- lnr(EXP,EXP)
-
- repeat
-
- GOAL
- run.
-
- CLAUSES
- run:-
- makewindow(1,71,7,"",1,15,9,50),
- write(" S Y M B O L I C D I F F E R E N T A T I O N"),nl,
- write(" ********************************************"),nl,
- field_attr(0,2,44,112),
- write(" An expression may include: "),nl,
- write(" addition, subtraction, multiplication,\n"),
- write(" division, exponents and logarithms.\n\n"),
- write(" e.g. x+x or x*(2+y)^2 or ln(1+1/(1-x))"),
- makewindow(3,7,7,"",11,3,14,73),
- clearwindow,diff.
-
- diff:-
- readexp(EXP),
- d(EXP,"x",EXP1),
- write("Differentiated expression. :\n"),
- writeexp(EXP1),
- write("\nReduced expression:\n"),
- reduce(EXP1,EXP2),writeexp(EXP2),
- write("\n\nHit any key to continue..."),readchar(_),fail,!.
-
- diff:-diff.
-
- repeat.
- repeat:- repeat.
-
- /*
- CLAUSES FOR DIFFERENTIATION
- */
-
-
- d(int(_),_,int(0)).
- d(var(X),X,int(1)):-!.
- d(var(_),_,int(0)).
- d(plus(U,V),X,plus(U1,V1)):-
- d(U,X,U1),
- d(V,X,V1).
- d(minus(U,V),X,minus(U1,V1)):-
- d(U,X,U1),
- d(V,X,V1).
- d(mult(U,V),X,plus(mult(U1,V),mult(U,V1))):-
- d(U,X,U1),
- d(V,X,V1).
- d(div(U,V),X,div(minus(mult(U1,V),mult(U,V1)),mult(V,V))):-
- d(U,X,U1),
- d(V,X,V1).
- d(ln(U),X,mult(div(int(1),U),U1)):-d(U,X,U1).
- d(potens(E1,int(I)),_,mult(int(I),potens(E1,int(I1)))):-I1=I-1.
-
-
- /*
- CLAUSES FOR READING OF AN EXPRESSION
- */
- readexp(EXP) :-
- repeat,
- clearwindow,
- cursor(11,1),
- write("<?> for help <ESC> to quit"),
- cursor(1,1),
- write("Write an expression: "),
- readchar(Fchar),
- checkhelp(Fchar),
- cursor(1,22),
- write(Fchar),
- readln(STR),!,
- frontchar(STR1,Fchar,STR),
- tokl(STR1,TOKL),
- s_exp(TOKL,OL,EXP),
- check(EXP,OL).
- readexp(int(0)):-exit.
-
- checkhelp('\27'):-exit.
- checkhelp(Fchar):-
- Fchar <> '?',!.
- checkhelp('?'):-
- makewindow(4,23,7,"",10,3,14,73),
- file_str("diff.hlp",I),
- display(I),
- removewindow,
- fail.
-
- check(_,[]):-!.
- check(EXP,_):-
- writeexp(EXP),
- write("<-syntax error\n"),
- fail.
-
- tokl(STR,[TOK|TOKL]):-
- fronttoken(STR,TOK,STR1),!,
- tokl(STR1,TOKL).
- tokl(_,[]).
-
-
- /*
- CLAUSES FOR PARSING OF AN EXPRESSION
- */
-
- s_exp(IL,OL,EXP):-plusexp(IL,OL,EXP).
-
- plusexp(IL,OL,EXP2):-
- multexp(IL,OL1,EXP1),
- plusexp1(OL1,OL,EXP1,EXP2).
-
- plusexp1(["+"|IL],OL,EXP1,EXP3):-!,
- multexp(IL,OL1,EXP2),
- plusexp1(OL1,OL,plus(EXP1,EXP2),EXP3).
- plusexp1(["-"|IL],OL,EXP1,EXP3):-!,
- multexp(IL,OL1,EXP2),
- plusexp1(OL1,OL,minus(EXP1,EXP2),EXP3).
- plusexp1(IL,IL,EXP,EXP).
-
- multexp(IL,OL,EXP2):-
- potensexp(IL,OL1,EXP1),
- multexp1(OL1,OL,EXP1,EXP2).
-
- multexp1(["*"|IL],OL,EXP1,EXP3):-!,
- potensexp(IL,OL1,EXP2),
- multexp1(OL1,OL,mult(EXP1,EXP2),EXP3).
- multexp1(["/"|IL],OL,EXP1,EXP3):-!,
- potensexp(IL,OL1,EXP2),
- multexp1(OL1,OL,div(EXP1,EXP2),EXP3).
- multexp1(IL,IL,EXP,EXP).
-
- potensexp(IL,OL,EXP2):-
- elmexp(IL,OL1,EXP1),
- potensexp1(OL1,OL,EXP1,EXP2).
- potensexp1(["^"|IL],OL,EXP1,EXP3):-!,
- elmexp(IL,OL1,EXP2),
- potensexp1(OL1,OL,potens(EXP1,EXP2),EXP3).
- potensexp1(IL,IL,EXP,EXP).
-
- elmexp(["("|IL],OL,EXP):-
- s_exp(IL,OL1,EXP),
- front(")",OL1,OL),!.
- elmexp(["("|IL],OL,EXP):-!,
- s_exp(IL,OL,EXP),
- write("ERROR: unmatched parentheses"),nl,
- write("\n\nHit any key to continue..."),readchar(_),fail,!.
- elmexp(["ln","("|IL],OL,ln(EXP)):-!,
- s_exp(IL,OL1,EXP),
- front(")",OL1,OL).
- elmexp([TALSTR|IL],IL,int(INT)):-str_int(TALSTR,INT),!.
- elmexp([NAME|IL],IL,var(NAME)).
-
- front(TOK,[TOK|L],L).
-
- /*
- CLAUSES FOR WRITING OF AN EXPRESSION
- */
-
- writeexp(var(NAME)):-write(NAME).
- writeexp(int(INT)) :-
- str_int(INTSTR,INT),
- write(INTSTR).
- writeexp(ln(EXP)) :-
- write("ln"),
- writepar(EXP).
- writeexp(plus(EXP1,EXP2)):-
- writeexp(EXP1),
- write("+"),
- writeexp(EXP2).
- writeexp(minus(EXP1,EXP2)):-
- writeexp(EXP1),
- write("-"),
- writeMINUS(EXP2).
- writeexp(mult(EXP1,EXP2)):-
- writeMINUS(EXP1),
- write("*"),
- writeMINUS(EXP2).
- writeexp(div(EXP1,EXP2)):-
- writeMULT(EXP1),
- write("/"),
- writeDIV(EXP2).
- writeexp(potens(EXP1,EXP2)):-
- writeMULT(EXP1),
- write("^"),
- writePOTENS(EXP2).
-
- writePOTENS(div(X,Y)):-!,writepar(div(X,Y)).
- writePOTENS(X):-writeDIV(X).
-
- writeDIV(mult(X,Y)):-!,writepar(mult(X,Y)).
- writeDIV(X):-writeMULT(X).
-
- writeMULT(minus(X,Y)):- !,writepar(minus(X,Y)).
- writeMULT(X):-writeMINUS(X).
-
- writeMINUS(plus(X,Y)):-!,writepar(plus(X,Y)).
- writeMINUS(X):-writeexp(X).
-
- writePAR(EXP):-
- write("("),
- writeexp(EXP),
- write(")").
-
- /*
- CLAUSES FOR REDUCTION OF AN EXPRESSION
- */
-
- reduce(plus(X,Y),R):- !,
- reduce(X,X1),
- reduce(Y,Y1),
- plusr(X1,Y1,R).
- reduce(minus(X,Y),R):-!,
- reduce(X,X1),
- reduce(Y,Y1),
- minusr(X1,Y1,R).
- reduce(mult(X,Y),R):-!,
- reduce(X,X1),
- reduce(Y,Y1),
- multr(X1,Y1,R).
- reduce(div(X,Y),R):-!,
- reduce(X,X1),
- reduce(Y,Y1),
- divr(X1,Y1,R).
- reduce(ln(X),R):-!,
- reduce(X,X1),
- lnr(X1,R).
- reduce(potens(E,int(1)),E):-!.
- reduce(R,R).
-
- /*
- CLAUSES FOR REDUCTION OF AN ADDITION EXPRESSION
- */
-
- plusr(int(0),X,X):-!.
- plusr(X,int(0),X):-!.
- plusr(int(X),int(Y),int(Z)):-!,
- X+Y=Z.
- plusr(X,X,mult(int(2),X)):-!.
- plusr(mult(int(I),X),X,mult(int(I1),X)):-!,
- I+1=I1.
- plusr(X,mult(int(I),X),mult(int(I1),X)):-!,
- I+1=I1.
- plusr(mult(int(I1),X),mult(int(I2),X),mult(int(I3),X)):-!,
- I1+I2=I3.
- plusr(int(I),X,plus(X,int(I))):-!.
- plusr(plus(X,int(I1)),int(I2),plus(X,int(I3))):-!,
- I1+I2=I3.
- plusr(plus(X,int(I1)),plus(Y,int(I2)),plus(R,int(I3))):-!,
- I1+I2=I3,
- plusr(X,Y,R).
- plusr(plus(X,int(I)),Y,plus(R,int(I))):-!,
- plusr(X,Y,R).
- plusr(X,Y,plus(X,Y)).
-
- /*
- CLAUSES FOR REDUCTION OF A MINUS EXPRESSION
- */
-
- minusr(int(X),int(Y),int(Z)):-!,
- Z=X-Y.
- minusr(X,int(0),X):-!.
- minusr(X,X,int(0)):-!.
- minusr(X,int(I),plus(X,int(I1))):-!,
- I1=-I.
- minusr(X,Y,minus(X,Y)).
-
- /*
- CLAUSES FOR REDUCTION OF A MULTIPLICATION EXPRESSION
- */
-
- multr(int(X),int(Y),int(Z)):-!,
- X*Y=Z.
- multr(int(0),_,int(0)):-!.
- multr(_,int(0),int(0)):-!.
- multr(int(1),X,X):-!.
- multr(X,int(1),X):-!.
- multr(mult(int(I1),X),int(I2),mult(int(I3),X)):-!,
- I1*I2=I3.
- multr(int(I1),mult(int(I2),X),mult(int(I3),X)):-!,
- I1*I2=I3.
- multr(mult(int(I1),X),mult(int(I2),Y),mult(int(I3),R)):-!,
- I1+I2=I3,
- multr(X,Y,R).
- multr(mult(int(I),X),Y,mult(int(I),R)):-!,
- multr(X,Y,R).
- multr(X,int(I),mult(int(I),X)):-!.
- multr(potens(X,int(I1)),potens(X,int(I2)),potens(X,int(I3))):-!,
- I3=I1+I2.
- multr(X,potens(X,int(I)),potens(X,int(I1))):-!,
- I1=I+1.
- multr(potens(X,int(I)),X,potens(X,int(I1))):-!,
- I1=I+1.
- multr(X,X,potens(X,int(2))):-!.
- multr(X,Y,mult(X,Y)).
-
- /*
- CLAUSES FOR REDUCTION OF A DIVISION EXPRESION
- */
-
- divr(int(0),_,int(0)):-!.
- divr(_,int(0),var("'endless'")):-!,
- write("division by zero"),nl.
- divr(X,int(1),X):-!.
- divr(X,Y,div(X,Y)).
-
- /*
- CLAUSES FOR REDUCTION OF A LOGARITHM EXPRESSION
- */
-
- lnr(int(0),var("endless")):-!,
- write("logarithm error"),nl.
- lnr(int(1),int(0)):-!.
- lnr(X,ln(X)).